﻿using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Windows.Forms;

namespace SerialServerManager
{
    public class SerialServerItem
    {
        // 基础属性
        public int Id { get; set; }
        public SerialConfig Config { get; set; } = new SerialConfig();

        // 字节数统计（总发送字节数、总写入字节数）
        public long TotalSendBytes { get; private set; }  // 串口→TCP 总字节数
        public long TotalWriteBytes { get; private set; } // TCP→串口 总字节数

        public bool IsOnline { get; private set; } // 改为私有set，避免外部误操作

        // 速率计算相关属性（字节/秒）
        private long _lastSendBytes;  // 上一次统计的发送字节数
        private long _lastWriteBytes; // 上一次统计的写入字节数
        public int SendRate { get; private set; }  // 发送速率（字节/秒）
        public int WriteRate { get; private set; } // 写入速率（字节/秒）

        // 通信组件
        private TcpListener _tcpListener;
        private SerialPort _serialPort;
        private Thread _listenThread;
        private Thread _reconnectThread; // 自动重连线程
        private TcpClient _connectedClient; // 改为单个客户端引用，而非列表
        private readonly object _clientLock = new object();
        private readonly object _counterLock = new object(); // 计数锁，保证线程安全
        private readonly object _serialLock = new object(); // 串口操作锁
        private int _reconnectCount; // 当前重连次数
        private bool _isReconnecting; // 是否正在重连中

        // 构造函数
        public SerialServerItem()
        {
            Config.BaudRate = 9600;
            Config.DataBits = 8;
            Config.Parity = Parity.None;
            Config.StopBits = StopBits.One;
            _serialPort = new SerialPort();
            _serialPort.ReadTimeout = 500; // 设置读取超时，避免阻塞
            _serialPort.WriteTimeout = 500; // 设置写入超时
            IsOnline = false;
        }

        // 计算速率的方法（每秒调用一次）
        public void CalculateRates()
        {
            lock (_counterLock)
            {
                // 计算发送速率
                SendRate = (int)(TotalSendBytes - _lastSendBytes);
                _lastSendBytes = TotalSendBytes;

                // 计算写入速率
                WriteRate = (int)(TotalWriteBytes - _lastWriteBytes);
                _lastWriteBytes = TotalWriteBytes;
            }
        }

        // 启动服务
        public void Start()
        {
            if (IsOnline) return;

            try
            {
                // 初始化串口
                _serialPort.PortName = Config.ComPort;
                _serialPort.BaudRate = Config.BaudRate;
                _serialPort.Parity = Config.Parity;
                _serialPort.DataBits = Config.DataBits;
                _serialPort.StopBits = Config.StopBits;
                _serialPort.Open();

                // 初始化TCP监听
                _tcpListener = new TcpListener(IPAddress.Parse(Config.IpAddress), Config.Port);
                _tcpListener.Start();

                // 启动监听线程
                _listenThread = new Thread(ListenForClients);
                _listenThread.IsBackground = true;
                _listenThread.Start();

                IsOnline = true;
                StatusChanged?.Invoke("服务启动成功");
                ResetCounters(); // 启动时重置计数器
            }
            catch (Exception ex)
            {
                StatusChanged?.Invoke($"启动失败: {ex.Message}");
                throw;
            }
        }

        // 监听客户端连接
        private void ListenForClients()
        {
            while (IsOnline)
            {
                try
                {
                    HandleClientConnection(_tcpListener.AcceptTcpClient());
                }
                catch (ThreadAbortException)
                {
                    break;
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"监听错误: {ex.Message}");
                }
            }
        }

        // 处理客户端连接（确保只有一个客户端能连接）
        private void HandleClientConnection(TcpClient client)
        {
            try
            {
                lock (_clientLock)
                {
                    // 检查是否已有连接客户端
                    if (_connectedClient != null && _connectedClient.Connected)
                    {
                        // 向新客户端发送提示并断开
                        using (var stream = client.GetStream())
                        {
                            var msg = System.Text.Encoding.UTF8.GetBytes("设备已被独占，无法连接");
                            stream.Write(msg, 0, msg.Length);
                        }
                        client.Close();
                        StatusChanged?.Invoke("拒绝新客户端连接：设备已被独占");
                        return;
                    }

                    // 保存新连接的客户端
                    _connectedClient = client;
                }

                string clientIp = ((IPEndPoint)client.Client.RemoteEndPoint).Address.ToString();
                StatusChanged?.Invoke($"客户端连接成功（IP：{clientIp}）");

                var clientThread = new Thread(HandleClient);
                clientThread.IsBackground = true;
                clientThread.Start(client);
            }
            catch (Exception ex)
            {
                StatusChanged?.Invoke($"客户端连接处理错误: {ex.Message}");
                client.Close();
            }
        }

        // 停止服务（overload：是否触发重连）
        public void Stop(bool triggerReconnect = false)
        {
            IsOnline = false;

            // 停止监听线程
            if (_listenThread != null && _listenThread.IsAlive)
            {
                _listenThread.Interrupt();
                _listenThread.Join(1000); // 等待线程结束
            }

            // 关闭TCP监听
            if (_tcpListener != null)
            {
                try
                {
                    _tcpListener.Stop();
                }
                catch (Exception ex)
                {
                    StatusChanged?.Invoke($"TCP监听关闭错误: {ex.Message}");
                }
                _tcpListener = null;
            }

            // 断开客户端连接
            lock (_clientLock)
            {
                if (_connectedClient != null)
                {
                    try
                    {
                        _connectedClient.Close();
                    }
                    catch (Exception ex)
                    {
                        StatusChanged?.Invoke($"客户端断开错误: {ex.Message}");
                    }
                    _connectedClient = null;
                }
            }

            // 关闭串口
            lock (_serialLock)
            {
                if (_serialPort != null && _serialPort.IsOpen)
                {
                    try
                    {
                        _serialPort.Close();
                    }
                    catch (Exception ex)
                    {
                        StatusChanged?.Invoke($"串口关闭错误: {ex.Message}");
                    }
                }
            }

            StatusChanged?.Invoke("服务已停止");

            // 如果需要触发重连，且启用了自动重连
            if (triggerReconnect && Config.AutoReconnect)
            {
                StartReconnectThread();
            }
            else
            {
                // 手动停止，重置计数器
                ResetCounters();
            }
        }

        // 启动自动重连线程
        private void StartReconnectThread()
        {
            if (_isReconnecting || !Config.AutoReconnect)
                return;

            _isReconnecting = true;
            _reconnectCount = 0;
            _reconnectThread = new Thread(ReconnectLoop);
            _reconnectThread.IsBackground = true;
            _reconnectThread.Start();
        }

        // 重连循环
        private void ReconnectLoop()
        {
            while (_isReconnecting)
            {
                // 检查是否超过最大重连次数
                if (Config.MaxReconnectTimes > 0 && _reconnectCount >= Config.MaxReconnectTimes)
                {
                    StatusChanged?.Invoke($"已达到最大最大重连次数（{Config.MaxReconnectTimes}次），停止重连");
                    _isReconnecting = false;
                    ReconnectCompleted?.Invoke(false);
                    return;
                }

                try
                {
                    _reconnectCount++;
                    StatusChanged?.Invoke($"正在进行第 {_reconnectCount} 次重连...");

                    // 尝试重新启动服务
                    Start();

                    if (IsOnline)
                    {
                        StatusChanged?.Invoke("重连成功");
                        _isReconnecting = false;
                        ReconnectCompleted?.Invoke(true);
                        return;
                    }
                }
                catch (Exception ex)
                {
                    StatusChanged?.Invoke($"重连失败: {ex.Message}");
                }

                // 等待重连间隔
                Thread.Sleep(Config.ReconnectInterval);
            }
        }

        // 处理客户端通信
        private void HandleClient(object obj)
        {
            var client = (TcpClient)obj;
            SerialDataReceivedEventHandler dataHandler = null;
            string clientIp = ((IPEndPoint)client.Client.RemoteEndPoint).Address.ToString();

            try
            {
                using (var ns = client.GetStream())
                {
                    var buffer = new byte[4096]; // 增大缓冲区，提高传输效率
                    int bytesRead;

                    // 串口数据接收事件（串口→TCP客户端）
                    dataHandler = (s, e) =>
                    {
                        try
                        {
                            if (!IsOnline || !client.Connected) return;

                            lock (_serialLock)
                            {
                                if (_serialPort == null || !_serialPort.IsOpen)
                                    return;

                                int bytesToRead = _serialPort.BytesToRead;
                                if (bytesToRead > 0)
                                {
                                    var data = new byte[bytesToRead];
                                    int readBytes = _serialPort.Read(data, 0, bytesToRead);

                                    if (readBytes > 0)
                                    {
                                        ns.Write(data, 0, readBytes);

                                        // 累加发送字节数（线程安全）
                                        lock (_counterLock)
                                        {
                                            TotalSendBytes += readBytes;
                                        }
                                    }
                                }
                            }
                        }
                        catch (TimeoutException)
                        {
                            // 读取超时，忽略（正常现象）
                        }
                        catch (Exception ex)
                        {
                            StatusChanged?.Invoke($"串口→TCP传输错误（客户端：{clientIp}）: {ex.Message}");
                            // 串口异常，触发重连
                            if (IsOnline)
                            {
                                Stop(true); // 停止服务并触发重连
                            }
                        }
                    };

                    lock (_serialLock)
                    {
                        if (_serialPort != null && _serialPort.IsOpen)
                        {
                            _serialPort.DataReceived += dataHandler;
                        }
                    }

                    // TCP客户端数据接收（TCP→串口）
                    while (IsOnline && client.Connected)
                    {
                        try
                        {
                            bytesRead = ns.Read(buffer, 0, buffer.Length);
                            if (bytesRead > 0)
                            {
                                lock (_serialLock)
                                {
                                    if (_serialPort != null && _serialPort.IsOpen)
                                    {
                                        _serialPort.Write(buffer, 0, bytesRead);

                                        // 累加写入字节数（线程安全）
                                        lock (_counterLock)
                                        {
                                            TotalWriteBytes += bytesRead;
                                        }
                                    }
                                    else
                                    {
                                        StatusChanged?.Invoke("串口未打开，无法写入数据");
                                        break;
                                    }
                                }
                            }
                            else
                            {
                                // 字节数为0，客户端已断开连接
                                StatusChanged?.Invoke($"客户端 {clientIp} 已断开连接");
                                break;
                            }
                        }
                        catch (Exception ex)
                        {
                            StatusChanged?.Invoke($"TCP→串口传输错误（客户端：{clientIp}）: {ex.Message}");
                            break;
                        }
                    }
                }
            }
            finally
            {
                // 移除事件绑定
                if (dataHandler != null)
                {
                    lock (_serialLock)
                    {
                        if (_serialPort != null)
                        {
                            _serialPort.DataReceived -= dataHandler;
                        }
                    }
                }

                // 清理客户端连接
                lock (_clientLock)
                {
                    if (_connectedClient == client)
                    {
                        _connectedClient = null;
                    }
                }

                client.Close();
                StatusChanged?.Invoke($"客户端 {clientIp} 连接已关闭");

                // 如果服务仍在线，且没有其他客户端连接，继续监听
                if (IsOnline)
                {
                    StatusChanged?.Invoke("等待新的客户端连接...");
                }
                else if (Config.AutoReconnect)
                {
                    // 服务已离线，触发重连
                    Stop(true);
                }
            }
        }

        // 重置统计计数器
        public void ResetCounters()
        {
            lock (_counterLock)
            {
                TotalSendBytes = 0;
                TotalWriteBytes = 0;
                _lastSendBytes = 0;
                _lastWriteBytes = 0;
                SendRate = 0;
                WriteRate = 0;
            }
        }

        // 状态通知事件（供UI订阅）
        public event Action<string> StatusChanged; // 状态变更通知（如"串口断开，正在重连..."）
        public event Action<bool> ReconnectCompleted; // 重连完成通知（参数：是否成功）
    }
}